import { Form} from "antd";
import {CSSProperties, useEffect, useState} from "react";
import {ComponentSetter, useComponentConfigStore} from "../../stores/component-config.tsx";
import {useComponentsStore} from "../../stores/components.tsx";
import CssEditor from "./CssEditor.tsx";
import {debounceHandle} from "../../utils/throttle.ts";
import styleToObject from "style-to-object"
import {renderStylesInput} from "./utils/renderStylesInput.tsx";

const ComponentStyle = () => {
    const [form] = Form.useForm();
    const [css, setCss] = useState<string>(`.comp{\n\n}`)
    const {currentComponentId, currentComponent, updateComponentStyles} = useComponentsStore();
    const {stylesSetter} = useComponentConfigStore();

    useEffect(() => {
        form.resetFields()
        const data = form.getFieldsValue();
        form.setFieldsValue({...data, ...currentComponent?.styles});
        setCss(toCssStr(currentComponent?.styles!))
    }, [currentComponent])

    if (!currentComponentId || !currentComponent) return null;

    function renderFormElement(setter: ComponentSetter) {
        return renderStylesInput(setter,currentComponent)
    }

    function valueChange(changeValues: CSSProperties) {
        const attr: string = Object.keys(changeValues)[0]
        debounceHandle(() => {
            if (!currentComponentId) return;
            if (changeValues?.color || changeValues?.backgroundColor) {
                {/*@ts-ignore*/}
                updateComponentStyles(currentComponentId, {[attr]: (changeValues[attr] as any).toRgbString()});
                return;
            }
            updateComponentStyles(currentComponentId, changeValues);

        }, 200)
    }

    const handleEditorChange = (value: string | undefined) => {
        if (value === undefined) return;
        debounceHandle(() => {
            let css: Record<string, any> = {};
            try {
                const cssStr = value.replace(/\/\*.*\*\//, '') // 去掉注释 /** */
                    .replace(/(\.?[^{]+{)/, '') // 去掉 .comp {
                    .replace('}', '');// 去掉 }

                styleToObject(cssStr, (name, value) => {
                    css[name.replace(/-\w/, (item) => item.toUpperCase().replace('-', ''))] = value;
                });
                updateComponentStyles(currentComponentId, {...form.getFieldsValue(), ...css}, true);
            } catch (e) {
            }
        }, 500)
    }

    const toCssStr = (css: Record<string, any>) => {
        let str = `.comp{\n`
        for (const key in css) {
            let value = css[key];
            if (!value) continue;
            // key 是否包含以下属性 和 是否以px结尾 包含且没有就添加px
            if (['width', 'height', 'top', 'left', 'bottom', 'right'].includes(key) && !value.toString().endsWith('px')) {
                if (['top', 'left', 'bottom', 'right', 'width', 'height'].includes(key) && !value.toString().startsWith('%')) {
                    str += `\t${key}:${value};\n`
                    continue
                }
                value += 'px'
            }
            const strArr = key.split('')
            let newKey = key
            strArr.forEach((item) => {
                if (/[A-Z]/.test(item)) {
                    newKey = newKey.replace(item, '-' + item.toLowerCase())
                }
            })

            str += `\t${newKey}:${value};\n`

        }
        str += `}`
        return str

    }

    return (
        <Form
            form={form}
            onValuesChange={valueChange}
            labelCol={{span: 8}}
            wrapperCol={{span: 14}}
            initialValues={{
                ...currentComponent.styles
            }}

        >
            <div className='h-[200px] border-[1px] border-[#ccc]'>
                <CssEditor value={css} onChange={handleEditorChange}/>
            </div>
            {
                stylesSetter?.map(setter => (
                    <Form.Item key={setter.name} label={setter.label}>
                        {renderFormElement(setter)}
                    </Form.Item>
                ))
            }
        </Form>
    )
};

export default ComponentStyle;